﻿using System;
using System.Linq.Expressions;
using System.Windows;
using Columbus.ActionResults;

namespace Columbus
{
    public abstract class Controller
    {
        [ThreadStatic]
        private static NavigationContext navigationContext;

        protected NavigationContext NavigationContext
        {
            get { return navigationContext; }
        }

        protected bool CancelRequested
        {
            get { return navigationContext.CancelRequested; }
        }

        public void Initialize(NavigationContext context)
        {
            navigationContext = context;
        }

        protected DoNothingResult Nothing()
        {
            return new DoNothingResult(navigationContext).NoNeedToSaveRequestInJournal();
        }

        protected BackResult Back()
        {
            return new BackResult(navigationContext).NoNeedToSaveRequestInJournal();
        }

        protected PageResult Page(string name, object model)
        {
            return new PageResult(name, model, navigationContext).NeedToSaveRequestInJournal();
        }

        protected PageResult Page(string name)
        {
            return new PageResult(name, null, navigationContext).NeedToSaveRequestInJournal();
        }

        protected PageResult Page(object model)
        {
            return new PageResult(navigationContext.Request.ActionName, model, navigationContext).NeedToSaveRequestInJournal();
        }

        protected PageResult Page()
        {
            return new PageResult(navigationContext.Request.ActionName, null, navigationContext).NeedToSaveRequestInJournal();
        }

        protected DialogResult Dialog(string name, object model)
        {
            return new DialogResult(name, model, navigationContext).NoNeedToSaveRequestInJournal();
        }

        protected DialogResult Dialog(string name)
        {
            return new DialogResult(name, null, navigationContext).NoNeedToSaveRequestInJournal();
        }

        protected DialogResult Dialog(object model)
        {
            return new DialogResult(navigationContext.Request.ActionName, model, navigationContext).NoNeedToSaveRequestInJournal();
        }

        protected DialogResult Dialog()
        {
            return new DialogResult(navigationContext.Request.ActionName, null, navigationContext).NoNeedToSaveRequestInJournal();
        }

        protected CloseDialogResult CloseDialog()
        {
            return new CloseDialogResult(navigationContext).NoNeedToSaveRequestInJournal();
        }

        protected MessageBoxActionResult MessageBox(string messageBoxText)
        {
            return new MessageBoxActionResult(navigationContext, messageBoxText);
        }

        protected MessageBoxActionResult MessageBox(string messageBoxText, string caption, MessageBoxButton button)
        {
            return new MessageBoxActionResult(navigationContext, messageBoxText, caption, button);
        }

        protected MessageBoxActionResult MessageBox(string messageBoxText, string caption, MessageBoxButton button, Action<MessageBoxResult> resultCallback)
        {
            return new MessageBoxActionResult(navigationContext, messageBoxText, caption, button, resultCallback);
        }

        protected RedirectResult<TController> Redirect<TController>(Expression<Func<TController, ActionResult>> actionSelector) where TController : Controller
        {
            return new RedirectResult<TController>(actionSelector, navigationContext).NeedToSaveRequestInJournal();
        }

        protected RedirectResult Redirect<TController>(string actionName, params object[] parameters) where TController : Controller
        {
            return new RedirectResult(typeof(TController).Name, actionName, navigationContext, parameters).NeedToSaveRequestInJournal();
        }

        protected RedirectResult Redirect(string controllerName, string actionName, params object[] parameters)
        {
            return new RedirectResult(controllerName, actionName, navigationContext, parameters).NeedToSaveRequestInJournal();
        }

        protected void ReportProgress(object progressValue)
        {
            var frame = navigationContext.Navigator.NavigationFrame;
            Dispatcher.Dispatch(() => frame.Progress = progressValue);
        }

        protected void DisallowCancelling()
        {
            var frame = navigationContext.Navigator.NavigationFrame;
            Dispatcher.Dispatch(() => frame.IsAllowedToCancel = false);
        }

        protected void AllowCancelling()
        {
            var frame = navigationContext.Navigator.NavigationFrame;
            Dispatcher.Dispatch(() => frame.IsAllowedToCancel = true);
        }
    }
}